package com.todo.member.application.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.todo.common.common.entity.response.page.PageResult;
import com.todo.common.common.enums.BizErrorCodeEnum;
import com.todo.common.common.exception.BizException;
import com.todo.component.redis.RedisService;
import com.todo.member.application.convert.MemberInfoConvert;
import com.todo.member.application.entity.bo.MemberMedalInfoBO;
import com.todo.member.application.entity.condition.MemberMedalConditionBO;
import com.todo.member.application.service.MemberMedalInfoService;
import com.todo.member.common.base.redis.MemberKeyBuild;
import com.todo.member.common.enums.MedalStatusEnum;
import com.todo.member.infrastructure.entity.condition.MemberMedalInfoCondition;
import com.todo.member.infrastructure.entity.po.MemberMedalInfoPO;
import com.todo.member.infrastructure.repository.MemberMedalInfoRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;

/**
 * @author azhebuxing
 * @date 2025/2/12 21:58
 * @description
 */
@Slf4j
@Service
public class MemberMedalInfoServiceImpl implements MemberMedalInfoService {

    @Resource
    private MemberMedalInfoRepository memberMedalInfoRepository;
    @Resource
    private RedisService redisService;


    @Override
    public Boolean insertMemberMedalInfo(MemberMedalInfoBO memberMedalInfoBO) {
        if (memberMedalInfoBO == null) {
            return false;
        }
        MemberMedalInfoPO codeData = memberMedalInfoRepository.queryMemberMedalInfoByMedalCode(memberMedalInfoBO.getMedalCode());
        if (codeData != null) {
            log.error("MemberMedalInfoService#insertMemberMedalInfo 添加会员勋章信息失败，勋章编码已存在 memberMedalInfoBO：【{}】", JSONObject.toJSONString(memberMedalInfoBO));
            throw new BizException(BizErrorCodeEnum.OPERATION_FAILED, "勋章编码已存在");
        }
        MemberMedalInfoPO titleData = memberMedalInfoRepository.queryMemberMedalInfoByTitle(memberMedalInfoBO.getTitle());
        if (titleData != null) {
            log.error("MemberMedalInfoService#insertMemberMedalInfo 添加会员勋章信息失败，勋章标题已存在 memberMedalInfoBO：【{}】", JSONObject.toJSONString(memberMedalInfoBO));
            throw new BizException(BizErrorCodeEnum.OPERATION_FAILED, "勋章标题已存在");
        }

        //TODO 规则逻辑可用判断 memberMedalInfoBO.getRule()

        MemberMedalInfoPO memberMedalInfoPO = MemberInfoConvert.convertToMemberMedalInfoPO(memberMedalInfoBO);
        Boolean inserted = memberMedalInfoRepository.insertMemberMedalInfo(memberMedalInfoPO);

        return inserted;
    }

    @Override
    public Boolean updateMemberMedalInfo(MemberMedalInfoBO memberMedalInfoBO) {
        if (memberMedalInfoBO == null || memberMedalInfoBO.getId() == null) {
            return false;
        }
        MemberMedalInfoBO alreadyData = queryMemberMedalInfoById(memberMedalInfoBO.getId());
        if (alreadyData == null) {
            log.error("MemberMedalInfoService#updateMemberMedalInfo 更新会员勋章信息失败，勋章不存在 memberMedalInfoBO：【{}】", JSONObject.toJSONString(memberMedalInfoBO));
            throw new BizException(BizErrorCodeEnum.OPERATION_FAILED, "勋章不存在");
        }
        if (MedalStatusEnum.RUNNING.equals(alreadyData.getStatus())) {
            log.error("MemberMedalInfoService#updateMemberMedalInfo 更新会员勋章信息失败，勋章正在使用 memberMedalInfoBO：【{}】", JSONObject.toJSONString(memberMedalInfoBO));
            throw new BizException(BizErrorCodeEnum.OPERATION_FAILED, "勋章正在使用");
        }
        if (!alreadyData.getMedalCode().equals(memberMedalInfoBO.getMedalCode())) {
            log.error("MemberMedalInfoService#updateMemberMedalInfo 更新会员勋章信息失败，勋章code禁止修改 memberMedalInfoBO：【{}】", JSONObject.toJSONString(memberMedalInfoBO));
            throw new BizException(BizErrorCodeEnum.OPERATION_FAILED, "勋章code禁止修改");
        }
        if (!alreadyData.getTitle().equals(memberMedalInfoBO.getTitle())) {
            MemberMedalInfoPO memberMedalInfoPO = memberMedalInfoRepository.queryMemberMedalInfoByTitle(memberMedalInfoBO.getTitle());
            if (memberMedalInfoPO != null) {
                log.error("MemberMedalInfoService#updateMemberMedalInfo 更新会员勋章信息失败，勋章标题已存在 memberMedalInfoBO：【{}】", JSONObject.toJSONString(memberMedalInfoBO));
                throw new BizException(BizErrorCodeEnum.OPERATION_FAILED, "勋章标题已存在");
            }
        }
        //TODO 规则逻辑可用判断 memberMedalInfoBO.getRule()
        memberMedalInfoBO.setStatus(MedalStatusEnum.DRAFT);
        MemberMedalInfoPO memberMedalInfoPO = MemberInfoConvert.convertToMemberMedalInfoPO(memberMedalInfoBO);
        Boolean updated = memberMedalInfoRepository.updateMemberMedalInfo(memberMedalInfoPO);
        return updated;
    }

    @Override
    public Boolean removeMemberMedalInfoById(Long id) {
        if (id == null || id < 0) {
            return false;
        }
        MemberMedalInfoBO alreadyData = queryMemberMedalInfoById(id);
        if (alreadyData == null) {
            return true;
        }
        if (MedalStatusEnum.RUNNING.equals(alreadyData.getStatus())) {
            log.error("MemberMedalInfoService#removeMemberMedalInfoById 删除会员勋章信息失败，勋章正在使用 memberMedalInfoBO：【{}】", JSONObject.toJSONString(alreadyData));
            throw new BizException(BizErrorCodeEnum.OPERATION_FAILED, "勋章正在使用");
        }
        Boolean updated = memberMedalInfoRepository.removeMemberMedalInfoById(id);
        return updated;
    }

    @Override
    public MemberMedalInfoBO queryMemberMedalInfoById(Long id) {
        if (id == null || id < 0) {
            return null;
        }
        String cacheValue = redisService.hGet(MemberKeyBuild.buildEffectiveMemberMedalKey(), String.valueOf(id));
        if (cacheValue != null) {
            MemberMedalInfoBO memberMedalInfoBO = JSONObject.parseObject(cacheValue, MemberMedalInfoBO.class);
            return memberMedalInfoBO;
        }
        MemberMedalInfoPO memberMedalInfoPO = memberMedalInfoRepository.queryMemberMedalInfoById(id);
        if (memberMedalInfoPO == null) {
            return null;
        }
        MemberMedalInfoBO memberMedalInfoBO = MemberInfoConvert.convertToMemberMedalInfoBO(memberMedalInfoPO);
        if (MedalStatusEnum.RUNNING.equals(MedalStatusEnum.getByType(memberMedalInfoPO.getStatus()))) {
            redisService.hSet(MemberKeyBuild.buildEffectiveMemberMedalKey(), String.valueOf(id), JSONObject.toJSONString(memberMedalInfoBO));
        }
        return memberMedalInfoBO;
    }

    @Override
    public Boolean updateMemberMedalInfoStatusById(Long id, MedalStatusEnum oldStatus, MedalStatusEnum newStatus) {
        if (id == null || id < 0 || oldStatus == null || newStatus == null) {
            return false;
        }
        if (oldStatus == newStatus) {
            return true;
        }
        MemberMedalInfoBO memberMedalInfoBO = queryMemberMedalInfoById(id);
        if (memberMedalInfoBO == null) {
            log.error("MemberMedalInfoService#updateMemberMedalInfoStatusById 更新会员勋章信息失败，勋章不存在 memberMedalInfoBO：【{}】", JSONObject.toJSONString(memberMedalInfoBO));
            return false;
        }
        Boolean updated = memberMedalInfoRepository.updateMemberMedalInfoStatusById(id, oldStatus, newStatus);
        if (!updated){
            return false;
        }
        if (oldStatus == MedalStatusEnum.RUNNING){
            redisService.hDel(MemberKeyBuild.buildEffectiveMemberMedalKey(), String.valueOf(id));
        }
        if (newStatus == MedalStatusEnum.RUNNING){
            String redisKey = MemberKeyBuild.buildEffectiveMemberMedalKey();
            memberMedalInfoBO.setStatus(newStatus);
            redisService.hSet(redisKey, String.valueOf(id), JSONObject.toJSONString(memberMedalInfoBO));
        }
        return true;
    }

    @Override
    public PageResult<MemberMedalInfoBO> queryMemberMedalInfoByPage(MemberMedalConditionBO memberMedalInfoBO) {
        if (memberMedalInfoBO == null){
            return PageResult.of(new ArrayList<>(), 0, 0, 0);
        }
        MemberMedalInfoCondition memberMedalInfoCondition = MemberInfoConvert.convertToMemberMedalInfoCondition(memberMedalInfoBO);
        PageResult<MemberMedalInfoPO> pageResult = memberMedalInfoRepository.queryMemberMedalInfoByCondition(memberMedalInfoCondition);
        if (pageResult == null){
            return PageResult.of(new ArrayList<>(), 0, 0, 0);
        }

        return MemberInfoConvert.convertToPageMemberMedalInfoBO(pageResult);
    }
}
